package com.pavlinic.mylisp.repl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;

import com.pavlinic.mylisp.Expression;
import com.pavlinic.mylisp.GlobalEvaluationContext;
import com.pavlinic.mylisp.parser.Parser;
import com.pavlinic.mylisp.parser.Tokenizer;

public class REPL {
	private final BufferedReader reader;
	private final Parser parser;
	private final PrintStream printer;

	public REPL(BufferedReader reader, Parser parser, PrintStream printer) {
		this.reader = reader;
		this.parser = parser;
		this.printer = printer;
	}

	public static void main(String[] args) throws IOException {
		// Wire together the objects
		final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
		final Parser parser = new Parser(new Tokenizer());
		final REPL repl = new REPL(reader, parser, System.out);
		Bootstrapper.getInstance().bootstrap();
		repl.go();
	}

	private void go() throws IOException {
		while (true) {
			try {
				final Expression expression = read();
				final Expression result = expression.evaluate(GlobalEvaluationContext.getInstance());
				printer.println(result);
			} catch (RuntimeException e) {
				e.printStackTrace();
			}
		}
	}

	private Expression read() throws IOException {
		printer.print(">");
		final String readLine = reader.readLine();
		return parser.parse(readLine);
	}
}
